package com.towker.core.mybatis;

import java.util.List;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;

import org.apache.ibatis.session.RowBounds;
import org.apache.ibatis.session.SqlSession;
import org.apache.ibatis.session.SqlSessionFactory;

import org.springframework.dao.support.DaoSupport;
import org.springframework.util.Assert;

/**
 * @author badqiu
 * @version 1.0
 */
@SuppressWarnings("unchecked")
public abstract class BaseMyBatisDao extends DaoSupport
{
	protected final Log log = LogFactory.getLog(getClass());
	// 注入sqlSessionFactory
	private SqlSessionFactory sqlSessionFactory;
	// 注入sqlSessionTemplate
	private SqlSessionTemplate sqlSessionTemplate;

	protected void checkDaoConfig() throws IllegalArgumentException
	{
		Assert.notNull(sqlSessionFactory, "sqlSessionFactory must be not null");
	}

	// 返回SqlSessionFactory
	public SqlSessionFactory getSqlSessionFactory()
	{
		return sqlSessionFactory;
	}

	// 注入sqlSessionFactory
	public void setSqlSessionFactory(SqlSessionFactory sqlSessionFactory)
	{
		this.sqlSessionFactory = sqlSessionFactory;
		this.sqlSessionTemplate = new SqlSessionTemplate(sqlSessionFactory);
	}

	// 返回sqlSessionTemplate
	public SqlSessionTemplate getSqlSessionTemplate()
	{
		return sqlSessionTemplate;
	}

	// public static interface SqlSessionCallback
	// {
	// public Object doInSession(SqlSession session);
	// }
	public static class SqlSessionTemplate
	{
		SqlSessionFactory sqlSessionFactory;

		public SqlSessionTemplate(SqlSessionFactory sqlSessionFactory)
		{
			this.sqlSessionFactory = sqlSessionFactory;
		}

		public Object execute(SqlSessionCallback action)
		{
			SqlSession session = null;
			try
			{
				session = sqlSessionFactory.openSession();
				Object result = action.doInSession(session);
				return result;
			}
			finally
			{
				if (session != null)
					session.close();
			}
		}

		// 添加
		public int insert(final String statement, final Object parameter)
		{
			return (Integer) execute(new SqlSessionCallback()
			{
				public Object doInSession(SqlSession session)
				{
					return session.insert(statement, parameter);
				}
			});
		}

		/**
		 * 删除
		 * @param statement
		 * @param parameter
		 * @return
		 */
		public int delete(final String statement, final Object parameter)
		{
			return (Integer) execute(new SqlSessionCallback()
			{
				public Object doInSession(SqlSession session)
				{
					return session.delete(statement, parameter);
				}
			});
		}

		// 更新
		public int update(final String statement, final Object parameter)
		{
			return (Integer) execute(new SqlSessionCallback()
			{
				public Object doInSession(SqlSession session)
				{
					return session.update(statement, parameter);
				}
			});
		}

		public Object selectOne(final String statement, final Object parameter)
		{
			return execute(new SqlSessionCallback()
			{
				public Object doInSession(SqlSession session)
				{
					return session.selectOne(statement, parameter);
				}
			});
		}

		public List selectList(final String statement, final Object parameter)
		{
			return (List) execute(new SqlSessionCallback()
			{
				public Object doInSession(SqlSession session)
				{
					return session.selectList(statement, parameter);
				}
			});
		}

		public List selectList(final String statement, final Object parameter, final int offset, final int limit)
		{
			return (List) execute(new SqlSessionCallback()
			{
				public Object doInSession(SqlSession session)
				{
					return session.selectList(statement, parameter, new RowBounds(offset, limit));
				}
			});
		}
	}

	public static interface SqlSessionCallback
	{
		public Object doInSession(SqlSession session);
	}
}
